using MultiplayerServerConnectionHandlers;
using UnityEngine;

public class GyroControllerDisplay : MonoBehaviour
{
	private ControllerData lastControlMessage;

	private bool gyroEnabled = true;

	private const float lowPassFilterFactor = 0.2f;

	private readonly Quaternion baseIdentity = Quaternion.Euler(90f, 0f, 0f);

	private readonly Quaternion landscapeRight = Quaternion.Euler(0f, 0f, 90f);

	private readonly Quaternion landscapeLeft = Quaternion.Euler(0f, 0f, -90f);

	private readonly Quaternion upsideDown = Quaternion.Euler(0f, 0f, 180f);

	private Quaternion cameraBase = Quaternion.identity;

	private Quaternion calibration = Quaternion.identity;

	private Quaternion baseOrientation = Quaternion.Euler(90f, 0f, 0f);

	private Quaternion baseOrientationRotationFix = Quaternion.identity;

	private Quaternion referanceRotation = Quaternion.identity;

	private bool debug = true;

	public ConnectionHandler myHandler
	{
		get
		{
			foreach (MessageHandler handler in BehaviourSingleton<GGUDPNetworkServer>.instance.handlers)
			{
				ConnectionHandler connectionHandler = handler as ConnectionHandler;
				if (connectionHandler != null)
				{
					return connectionHandler;
				}
			}
			return null;
		}
	}

	protected void Start()
	{
		AttachGyro();
	}

	protected void Update()
	{
		bool flag = false;
		for (int num = myHandler.unreadMessages.Count - 1; num >= 0; num--)
		{
			if (myHandler.unreadMessages[num].type == UDPMessageBase.MessageType.ControllerDataMessage)
			{
				Debug.Log("received message");
				ControllerData message = myHandler.unreadMessages[num].GetMessage<ControllerData>();
				if (!flag)
				{
					flag = true;
					bool flag2 = lastControlMessage == null;
					lastControlMessage = message;
					base.transform.rotation = Quaternion.Slerp(base.transform.rotation, cameraBase * (ConvertRotation(referanceRotation * lastControlMessage.attitude) * GetRotFix()), 0.2f);
				}
				myHandler.unreadMessages.RemoveAt(num);
			}
		}
	}

	protected void OnGUI()
	{
		if (debug)
		{
			GUILayout.Label("Orientation: " + ((lastControlMessage == null) ? Screen.orientation : ((ScreenOrientation)lastControlMessage.screenOrientation)));
			GUILayout.Label("Calibration: " + calibration);
			GUILayout.Label("Camera base: " + cameraBase);
			GUILayout.Label("input.gyro.attitude: " + ((lastControlMessage == null) ? Input.gyro.attitude : lastControlMessage.attitude));
			GUILayout.Label("transform.rotation: " + base.transform.rotation);
			if (GUILayout.Button("On/off gyro: " + (lastControlMessage != null || Input.gyro.enabled), GUILayout.Height(100f)))
			{
			}
			if (GUILayout.Button("On/off gyro controller: " + gyroEnabled, GUILayout.Height(100f)))
			{
			}
			if (GUILayout.Button("Update gyro calibration (Horizontal only)", GUILayout.Height(80f)))
			{
				UpdateCalibration(true);
			}
			if (GUILayout.Button("Update camera base rotation (Horizontal only)", GUILayout.Height(80f)))
			{
				UpdateCameraBaseRotation(true);
			}
			if (GUILayout.Button("Reset base orientation", GUILayout.Height(80f)))
			{
				ResetBaseOrientation();
			}
			if (GUILayout.Button("Reset camera rotation", GUILayout.Height(80f)))
			{
				base.transform.rotation = Quaternion.identity;
			}
		}
	}

	private void AttachGyro()
	{
		gyroEnabled = true;
		ResetBaseOrientation();
		UpdateCalibration(true);
		UpdateCameraBaseRotation(true);
		RecalculateReferenceRotation();
	}

	private void DetachGyro()
	{
		gyroEnabled = false;
	}

	private void UpdateCalibration(bool onlyHorizontal)
	{
		if (onlyHorizontal)
		{
			Quaternion quaternion = ((lastControlMessage == null) ? Input.gyro.attitude : lastControlMessage.attitude);
			Vector3 vector = quaternion * -Vector3.forward;
			vector.z = 0f;
			if (vector == Vector3.zero)
			{
				calibration = Quaternion.identity;
			}
			else
			{
				calibration = Quaternion.FromToRotation(baseOrientationRotationFix * Vector3.up, vector);
			}
		}
		else
		{
			Quaternion quaternion2 = ((lastControlMessage == null) ? Input.gyro.attitude : lastControlMessage.attitude);
			calibration = quaternion2;
		}
	}

	private void UpdateCameraBaseRotation(bool onlyHorizontal)
	{
		if (onlyHorizontal)
		{
			Vector3 forward = base.transform.forward;
			forward.y = 0f;
			if (forward == Vector3.zero)
			{
				cameraBase = Quaternion.identity;
			}
			else
			{
				cameraBase = Quaternion.FromToRotation(Vector3.forward, forward);
			}
		}
		else
		{
			cameraBase = base.transform.rotation;
		}
	}

	private static Quaternion ConvertRotation(Quaternion q)
	{
		return new Quaternion(q.x, q.y, 0f - q.z, 0f - q.w);
	}

	private Quaternion GetRotFix()
	{
		return Quaternion.identity;
	}

	private void ResetBaseOrientation()
	{
		baseOrientationRotationFix = GetRotFix();
		baseOrientation = baseOrientationRotationFix * baseIdentity;
	}

	private void RecalculateReferenceRotation()
	{
		referanceRotation = Quaternion.Inverse(baseOrientation) * Quaternion.Inverse(calibration);
	}
}
